﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using SharePoint.Contrib.Extensions;
using System.Xml.Linq;
using System.IO;

namespace TestData
{
    class Program
    {
        static void Main(string[] args)
        {
            SetupLookupLists();
        }

        private static void SetupLookupLists()
        {
            DisposeBooksSiteAfterUsage(site =>
                {
                    List<SPList> lists = new List<SPList>
                    {
                        site.CreateList("CategoryLevel1").AsList(),
                        site.CreateList("CategoryLevel2").AsList(),
                        site.CreateList("CategoryLevel3").AsList()
                    };

                    Console.WriteLine("Lists created");

                    var category01 = lists.Find(spl => spl.RootFolder.Name.Equals("CategoryLevel1", StringComparison.Ordinal));
                    var category02 = lists.Find(spl => spl.RootFolder.Name.Equals("CategoryLevel2", StringComparison.Ordinal));
                    var category03 = lists.Find(spl => spl.RootFolder.Name.Equals("CategoryLevel3", StringComparison.Ordinal));

                    CreateLookupBetween(category01, category02);
                    CreateLookupBetween(category02, category03);
                    Console.WriteLine("Lookups created");

                    PopulateWithData(category01, category02, category03);
                    Console.WriteLine("Data in lists populated");
                    
                });
        }

        private static void PopulateWithData(SPList level01, SPList level02, SPList level03)
        {
            var xml = XElement.Load(Path.Combine(Directory.GetCurrentDirectory(), "BookCategoryListData.xml"));

            var categories = from category01 in xml.Descendants("CategoryLevel1")
                             select new
                             {
                                 Name = category01.Attribute("name").Value,
                                 NextLevel = from category02 in category01.Descendants("CategoryLevel2")
                                             select new
                                             {
                                                 Name = category02.Attribute("name").Value,
                                                 NextLevel = from category03 in category02.Descendants("CategoryLevel3")
                                                             select new
                                                             {
                                                                 Name = category03.Attribute("name").Value
                                                             }
                                             }

                             };

            foreach (var category in categories)
            {
                if (level01.ItemCount == 0)
                {
                    // add all level 01 values
                    var item01 = level01.Items.Add();
                    item01[SPBuiltInFieldId.Title] = category.Name;
                    item01.Update();

                    foreach (var category02 in category.NextLevel)
                    {
                        // add all level 02 values
                        var item02 = level02.Items.Add();
                        item02[SPBuiltInFieldId.Title] = category02.Name;
                        item02.Update();

                        // create lookup between 01 and 02
                        var lookup01 = item01["nextlevel"] as SPFieldLookupValueCollection;
                        lookup01.Add(new SPFieldLookupValue(item02.ID, item02.Title));
                        item01["nextlevel"] = lookup01;
                        item01.SystemUpdate();

                        foreach (var category03 in category02.NextLevel)
                        {
                            // add all level 03 values
                            var item03 = level03.Items.Add();
                            item03[SPBuiltInFieldId.Title] = category03.Name;
                            item03.Update();

                            // create lookup between 02 and 03
                            var lookup02 = item02["nextlevel"] as SPFieldLookupValueCollection;
                            lookup02.Add(new SPFieldLookupValue(item03.ID, item03.Title));
                            item02["nextlevel"] = lookup02;
                            item02.SystemUpdate();
                        }
                    }
                }

            }

        }

        private static void CreateLookupBetween(SPList parent, SPList child)
        {
            if (parent.Fields.ContainsField("nextlevel") == false)
            {
                parent.Fields.AddLookup("nextlevel", child.ID, false);
            }

            var lookup = parent.Fields["nextlevel"] as SPFieldLookup;
            lookup.LookupField = "Title";
            lookup.Title = "Next Category";
            lookup.AllowMultipleValues = true;
            lookup.Update();
        }

        private static void DisposeBooksSiteAfterUsage(Action<SPWeb> action)
        {
            using (SPSite sitecollection = new SPSite("http://localhost/sites/books"))
            {
                using (SPWeb site = sitecollection.RootWeb)
                {
                    action(site);
                }
            }
        }
    }
}